package mpbe.geometria;

/*
 * Este codigo es software libre y se encuentra licenciado 
 * bajo los términos de la Licencia Pública General de GNU versión 3 
 * según se encuentra publicada por la Free Software Foundation.
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Autor: Martin Pablo Bellanca <martin.bellanca@gmail.com>
 * web: http://mpbe.blogspot.com/
 */

import java.lang.reflect.Array;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;


public class Poligono {
	private Vector<Punto> puntos;
	
	
	public Poligono(){
		puntos = new Vector<Punto>();
	}
	public Poligono(Vector<Punto> puntos){
		this.puntos = puntos;
	}
	public Poligono(Punto [] puntos) {
		this.puntos = new Vector<Punto>();
		for (int ii=0; ii<=puntos.length; ii++) this.puntos.add(puntos[ii]);
	}

	
	//****************************************************************
	//Getters and Setters
	//****************************************************************
	public Vector<Punto> getPuntos() {return puntos;}
	public void setPuntos(Vector<Punto> puntos) {this.puntos = puntos;}
	public void setPuntos(Punto [] puntos) {
		for (int ii=0; ii<puntos.length; ii++) this.puntos.add(puntos[ii]);
	}
	public int [] getArray_int() {
		int [] res = new int[puntos.size()*2];
		for (int ii=0; ii<puntos.size(); ii++) {
			res[ii*2] = (int)puntos.get(ii).getX();
			res[ii*2+1] = (int)puntos.get(ii).getY();
			
		}
		return res;
	}
	public Punto [] getArrayPuntos() {
		Punto [] res = new Punto[puntos.size()];
		for (int ii=0; ii<puntos.size(); ii++) res[ii] = puntos.get(ii);
		return res;
	}
	public Punto set(int index, Punto element) {return puntos.set(index, element);}
	public Punto firstElement() {return puntos.firstElement();}
	public Punto get(int index) {return puntos.get(index);}
	public Punto lastElement() {return puntos.lastElement();}
	public Recta getRecta(int valor) {
		Recta res;
		if (valor>-1 && valor <puntos.size()) {
			Punto pi = puntos.get(valor);
			Punto pf;
			if (valor!=(puntos.size()-1)) 
				pf = puntos.get(valor+1);
			else
				pf = puntos.get(0);
			res = new Recta(pi, pf);
		} else res = null;
		return res;
	}

	//****************************************************************
	// Delegate method
	//****************************************************************
	public void add(int index, Punto element) {puntos.add(index, element);}
	public boolean add(Punto e) {return puntos.add(e);}

	public int capacity() {return puntos.capacity();}
	public void clear() {puntos.clear();} 
	public Object clone() {return puntos.clone();}

	public void copyInto(Object[] anArray) {puntos.copyInto(anArray);}
	public boolean equals(Object o) {return puntos.equals(o);}

	public int indexOf(Object arg0, int arg1) {return puntos.indexOf(arg0, arg1);}
	public int indexOf(Object o) {return puntos.indexOf(o);}

	public boolean isEmpty() {return puntos.isEmpty();}
	public Iterator<Punto> iterator() {return puntos.iterator();}
	
	public int lastIndexOf(Object arg0, int arg1) {return puntos.lastIndexOf(arg0, arg1);}
	public int lastIndexOf(Object o) {return puntos.lastIndexOf(o);}

	public ListIterator<Punto> listIterator() {return puntos.listIterator();}
	public ListIterator<Punto> listIterator(int index) {return puntos.listIterator(index);}

	public Punto remove(int index) {return puntos.remove(index);}

	public boolean remove(Object o) {return puntos.remove(o);}

	public void setSize(int arg0) {puntos.setSize(arg0);}
	public int size() {return puntos.size();}

	public List<Punto> subList(int fromIndex, int toIndex) {return puntos.subList(fromIndex, toIndex);}

	public Object[] toArray() {return puntos.toArray();}
	public <T> T[] toArray(T[] a) {return puntos.toArray(a);}
	public String toString() {return puntos.toString();}

	public void trimToSize() {puntos.trimToSize();}
	

	//**********************************************************************
	// Operaciones sobre el poligono
	//**********************************************************************
	public Poligono offset(double dist) {
		
		Recta rf;
		Recta r1;
		Recta ro0;
		Recta ro1;
		Poligono resP = new Poligono(); 
		Punto pi;
		
		// obtiene la primer recta anterior
		rf = new Recta(puntos.get(puntos.size()-1), puntos.get(0));
		ro0 = rf.offset(dist);
		
		for (int ii=1; ii<=puntos.size(); ii++) {
			// obtiene la recta actual
			if (ii!=puntos.size())
				r1 = new Recta(puntos.get(ii-1), puntos.get(ii));
			else
				r1 = rf;
			ro1 = r1.offset(dist);
			// obtiene el punto de interseccion y lo guarda en resP
			pi = ro0.interseccion(ro1);
			resP.add(pi);
			// guarda la recta anterior
			ro0 =ro1;
		}
		
		return resP;
	}
	public Poligono rotar(Punto centro, double anguloRad) {
		Poligono res = new Poligono();
		Iterator<Punto> it = puntos.iterator();
		mpbe.geometria.Vector p;
		do {
			p = new mpbe.geometria.Vector (it.next());
			res.add(p.rotar(centro, anguloRad).getPunto());
		} while (it.hasNext());
		return res;
	}
	public Poligono escalar(double valor) {
		Poligono res = new Poligono();
		Iterator<Punto> it = puntos.iterator();
		mpbe.geometria.Vector p;
		do {
			p = new mpbe.geometria.Vector (it.next());
			res.add(p.escalar(valor).getPunto());
		} while (it.hasNext());
		return res;
	}
	public Poligono escalar(double valorX, double valorY) {
		Poligono res = new Poligono();
		Iterator<Punto> it = puntos.iterator();
		mpbe.geometria.Vector p;
		do {
			p = new mpbe.geometria.Vector (it.next());
			res.add(p.escalar(valorX, valorY).getPunto());
		} while (it.hasNext());
		return res;
	}
	public Poligono mover(double x, double y) {
		Poligono res = new Poligono();
		Iterator<Punto> it = puntos.iterator();
		Punto p;
		do {
			p = it.next();
			res.add(p.mover(x, y));
		} while (it.hasNext());
		return res;
	}
	
	public mpbe.geometria.Vector [] distancias(Punto punto) {
		Recta r;
		Punto pi;
		Punto pf;
		
		mpbe.geometria.Vector [] res;
		res = new mpbe.geometria.Vector[puntos.size()];
		
		for (int ii=1; ii<=puntos.size(); ii++) {
			// obtiene la recta actual
			pi = puntos.get(ii-1);
			if (ii != puntos.size())pf = puntos.get(ii); else pf = puntos.get(0);
			r = new Recta(pi, pf);
			
			// buscar la distancia
			res[ii-1] = r.distancia(punto);
			
		}
		
		
		return res;
		
	}
}
